package com.yc.bigdata.flink.demo;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.utils.ParameterTool;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;

import java.text.SimpleDateFormat;
import java.util.Date;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.ToString;

/**
 * <p>服务启动NL</p>
 * nc -l 9000
 * 9000端口号随意指定
 *
 * @author: YuanChilde
 * @date: 2020-02-10 9:33
 * @version: 1.0
 * Modification History:
 * Date    Author      Version     Description
 * -----------------------------------------------------------------
 * 2020-02-10 9:33    YuanChilde     1.0        新增
 */
public class DataStreamWordCountBySocket {

    private final static SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    public static void main(String[] args) {
        String[] args1 = {"--port","9111"};
        int port;
        try{
            ParameterTool parameterTool = ParameterTool.fromArgs(args1);
            port = parameterTool.getInt("port");
        }catch (Exception e){
            System.err.println("No port specified. Please run 'SocketWindowWordCount --port <port>'");
            port = 9111;
        }

        //获取运行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        /*StreamExecutionEnvironment env = StreamExecutionEnvironment.createRemoteEnvironment("dev.dongbaosoft.com",6123,"/home/kason/workspace/BigdataComponents/target/BigdataComponents-1.0-SNAPSHOT.jar");
        */env.getConfig().disableSysoutLogging();
/*        env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);*/

        DataStreamSource<String> text = env.socketTextStream("dev.dongbaosoft.com", port, "\n");

        DataStream<WordWithCount> windowCount = text.flatMap(new FlatMapFunction<String, WordWithCount>() {
            @Override
            public void flatMap(String value, Collector<WordWithCount> out) throws Exception {
                String[] splits = value.split("\\s");
                for (String word:splits) {
                    out.collect(new WordWithCount(word,1L,simple.format(new Date(System.currentTimeMillis()))));
                }
            }
        })
                .keyBy("word")
                //指定计算数据的窗口大小和滑动窗口大小
                .timeWindow(Time.seconds(1))
                .sum("count");
        //把数据打印到控制台,使用一个并行度
        windowCount.print().setParallelism(1);
        //注意：因为flink是懒加载的，所以必须调用execute方法，上面的代码才会执行
        try {
            env.execute("Socket Window WordCount");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @ToString @AllArgsConstructor @NoArgsConstructor
    public static class WordWithCount{
        public String word;
        public long count;
        public String time;
    }
}
